package edu.sdjzu.exam.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import edu.sdjzu.exam.mapper.QuestionMapper;
import edu.sdjzu.exam.mapper.QuestionOptionsMapper;
import edu.sdjzu.exam.domain.question.Question;
import edu.sdjzu.exam.domain.question.QuestionOption;
import edu.sdjzu.exam.dto.QuestionCreateDTO;
import edu.sdjzu.exam.dto.QuestionDTO;
import edu.sdjzu.exam.dto.QuestionUpdateDTO;

import edu.sdjzu.exam.service.question.QuestionService;
import edu.sdjzu.exam.service.course.CourseManagementService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class QuestionServiceImpl implements QuestionService {

    private final QuestionMapper questionMapper;
    private final QuestionOptionsMapper questionOptionsMapper;
    private final CourseManagementService courseManagementService;

    @Override
    @Transactional
    public Long createQuestion(QuestionCreateDTO createDTO) {
        Long createdBy = StpUtil.getLoginIdAsLong();
        
        // 检查课程权限
        if (!courseManagementService.hasPermission(createdBy, createDTO.getCourseId(), "write")) {
            throw new RuntimeException("无权限在该课程中创建题目");
        }

        Question question = new Question();
        question.setContent(createDTO.getContent());
        question.setQuestionType(createDTO.getQuestionType());
        question.setReferenceAnswer(createDTO.getReferenceAnswer());
        question.setSubject(createDTO.getSubject());
        question.setDifficulty(createDTO.getDifficulty());
        question.setCreatedBy(createdBy);
        question.setCourseId(createDTO.getCourseId());

        questionMapper.insertQuestion(question);
        Long questionId = question.getQuestionId();

        if ("single_choice".equals(createDTO.getQuestionType()) ||
                "multiple_choice".equals(createDTO.getQuestionType())) {
            if (createDTO.getOptions() != null && !createDTO.getOptions().isEmpty()) {
                for (QuestionCreateDTO.QuestionOptionDTO optionDTO : createDTO.getOptions()) {
                    QuestionOption option = new QuestionOption();
                    option.setQuestionId(questionId);
                    option.setContent(optionDTO.getContent());
                    option.setIsCorrect(optionDTO.getIsCorrect());
                    option.setOptionOrder(optionDTO.getOptionOrder());
                    questionOptionsMapper.insertOption(option);
                }
            }
        }

        return questionId;
    }

    @Override
    public QuestionDTO getQuestion(Long questionId) {
        Question question = questionMapper.selectQuestionById(questionId);
        if (question == null) {
            throw new RuntimeException("题目不存在");
        }
        
        // 权限检查：只对老师角色进行课程权限检查
        Long userId = StpUtil.getLoginIdAsLong();
        List<String> roles = StpUtil.getRoleList();
        
        // 如果是老师角色，需要检查课程权限
        if (roles.contains("teacher")) {
            if (!courseManagementService.hasPermission(userId, question.getCourseId(), "read")) {
                throw new RuntimeException("无权限访问该课程的题目");
            }
        }
        // 学生角色不需要课程权限检查，可以在考试中访问题目

        QuestionDTO dto = new QuestionDTO();
        dto.setQuestionId(question.getQuestionId());
        dto.setContent(question.getContent());
        dto.setQuestionType(question.getQuestionType());
        dto.setReferenceAnswer(question.getReferenceAnswer());
        dto.setSubject(question.getSubject());
        dto.setDifficulty(question.getDifficulty());
        dto.setCreatedBy(question.getCreatedBy());
        dto.setCourseId(question.getCourseId()); // 添加课程ID
        dto.setCreatedAt(question.getCreatedAt());
        dto.setUpdatedAt(question.getUpdatedAt());

        List<QuestionOption> options = questionOptionsMapper.selectOptionsByQuestionId(questionId);
        List<QuestionDTO.QuestionOptionDTO> optionDTOs = options.stream().map(opt -> {
            QuestionDTO.QuestionOptionDTO optionDTO = new QuestionDTO.QuestionOptionDTO();
            optionDTO.setOptionId(opt.getOptionId());
            optionDTO.setQuestionId(opt.getQuestionId());
            optionDTO.setContent(opt.getContent());
            optionDTO.setIsCorrect(opt.getIsCorrect());
            optionDTO.setOptionOrder(opt.getOptionOrder());
            return optionDTO;
        }).collect(Collectors.toList());
        dto.setOptions(optionDTOs);

        return dto;
    }

    @Override
    @Transactional
    public void updateQuestion(QuestionUpdateDTO updateDTO) {
        Question question = questionMapper.selectQuestionById(updateDTO.getQuestionId());
        if (question == null) {
            throw new RuntimeException("题目不存在");
        }
        
        // 检查老师是否有该课程的写权限
        Long teacherId = StpUtil.getLoginIdAsLong();
        if (!courseManagementService.hasPermission(teacherId, question.getCourseId(), "write")) {
            throw new RuntimeException("无权限修改该课程的题目");
        }

        question.setContent(updateDTO.getContent());
        question.setQuestionType(updateDTO.getQuestionType());
        question.setReferenceAnswer(updateDTO.getReferenceAnswer());
        question.setSubject(updateDTO.getSubject());
        question.setDifficulty(updateDTO.getDifficulty());
        questionMapper.updateQuestion(question);

        if ("single_choice".equals(updateDTO.getQuestionType()) ||
                "multiple_choice".equals(updateDTO.getQuestionType())) {
            questionOptionsMapper.deleteOptionsByQuestionId(updateDTO.getQuestionId());
            if (updateDTO.getOptions() != null && !updateDTO.getOptions().isEmpty()) {
                for (QuestionUpdateDTO.QuestionOptionDTO optionDTO : updateDTO.getOptions()) {
                    QuestionOption option = new QuestionOption();
                    option.setQuestionId(updateDTO.getQuestionId());
                    option.setContent(optionDTO.getContent());
                    option.setIsCorrect(optionDTO.getIsCorrect());
                    option.setOptionOrder(optionDTO.getOptionOrder());
                    questionOptionsMapper.insertOption(option);
                }
            }
        }
    }

    @Override
    @Transactional
    public void deleteQuestion(Long questionId) {
        Question question = questionMapper.selectQuestionById(questionId);
        if (question == null) {
            throw new RuntimeException("题目不存在");
        }
        
        // 检查老师是否有该课程的写权限
        Long teacherId = StpUtil.getLoginIdAsLong();
        if (!courseManagementService.hasPermission(teacherId, question.getCourseId(), "write")) {
            throw new RuntimeException("无权限删除该课程的题目");
        }

        questionOptionsMapper.deleteOptionsByQuestionId(questionId);
        questionMapper.deleteQuestion(questionId);
    }

    @Override
    public List<QuestionDTO> listQuestionsByCreator() {
        Long teacherId = StpUtil.getLoginIdAsLong();
        
        // 获取老师有权限的所有课程
        List<edu.sdjzu.exam.domain.course.Course> teacherCourses = courseManagementService.getTeacherCourses(teacherId);
        
        if (teacherCourses.isEmpty()) {
            return List.of(); // 如果老师没有任何课程权限，返回空列表
        }
        
        // 获取所有课程ID
        List<Long> courseIds = teacherCourses.stream()
                .map(edu.sdjzu.exam.domain.course.Course::getCourseId)
                .collect(Collectors.toList());
        
        // 获取老师在这些课程中创建的题目
        List<Question> questions = questionMapper.selectQuestionsByCreator(teacherId)
                .stream()
                .filter(question -> courseIds.contains(question.getCourseId()))
                .collect(Collectors.toList());
        
        return questions.stream().map(question -> {
            QuestionDTO dto = new QuestionDTO();
            dto.setQuestionId(question.getQuestionId());
            dto.setContent(question.getContent());
            dto.setQuestionType(question.getQuestionType());
            dto.setReferenceAnswer(question.getReferenceAnswer());
            dto.setSubject(question.getSubject());
            dto.setDifficulty(question.getDifficulty());
            dto.setCreatedBy(question.getCreatedBy());
            dto.setCourseId(question.getCourseId()); // 添加课程ID
            dto.setCreatedAt(question.getCreatedAt());
            dto.setUpdatedAt(question.getUpdatedAt());

            List<QuestionOption> options = questionOptionsMapper.selectOptionsByQuestionId(question.getQuestionId());
            List<QuestionDTO.QuestionOptionDTO> optionDTOs = options.stream().map(opt -> {
                QuestionDTO.QuestionOptionDTO optionDTO = new QuestionDTO.QuestionOptionDTO();
                optionDTO.setOptionId(opt.getOptionId());
                optionDTO.setQuestionId(opt.getQuestionId());
                optionDTO.setContent(opt.getContent());
                optionDTO.setIsCorrect(opt.getIsCorrect());
                optionDTO.setOptionOrder(opt.getOptionOrder());
                return optionDTO;
            }).collect(Collectors.toList());
            dto.setOptions(optionDTOs);

            return dto;
        }).collect(Collectors.toList());
    }
    
    @Override
    public List<QuestionDTO> listQuestionsByCourse(Long courseId) {
        Long userId = StpUtil.getLoginIdAsLong();
        List<String> roles = StpUtil.getRoleList();
        
        // 权限检查：只对老师角色进行课程权限检查
        if (roles.contains("teacher")) {
            if (!courseManagementService.hasPermission(userId, courseId, "read")) {
                throw new RuntimeException("无权限访问该课程的题目");
            }
        }
        // 学生角色不需要课程权限检查
        
        // 获取该课程的所有题目
        List<Question> questions = questionMapper.selectQuestionsByCourse(courseId);
        
        return questions.stream().map(question -> {
            QuestionDTO dto = new QuestionDTO();
            dto.setQuestionId(question.getQuestionId());
            dto.setContent(question.getContent());
            dto.setQuestionType(question.getQuestionType());
            dto.setReferenceAnswer(question.getReferenceAnswer());
            dto.setSubject(question.getSubject());
            dto.setDifficulty(question.getDifficulty());
            dto.setCreatedBy(question.getCreatedBy());
            dto.setCourseId(question.getCourseId());
            dto.setCreatedAt(question.getCreatedAt());
            dto.setUpdatedAt(question.getUpdatedAt());
            
            // 获取选项
            List<QuestionOption> options = questionOptionsMapper.selectOptionsByQuestionId(question.getQuestionId());
            List<QuestionDTO.QuestionOptionDTO> optionDTOs = options.stream().map(opt -> {
                QuestionDTO.QuestionOptionDTO optionDTO = new QuestionDTO.QuestionOptionDTO();
                optionDTO.setOptionId(opt.getOptionId());
                optionDTO.setQuestionId(opt.getQuestionId());
                optionDTO.setContent(opt.getContent());
                optionDTO.setIsCorrect(opt.getIsCorrect());
                optionDTO.setOptionOrder(opt.getOptionOrder());
                return optionDTO;
            }).collect(Collectors.toList());
            dto.setOptions(optionDTOs);
            
            return dto;
        }).collect(Collectors.toList());
    }
}